package mtc.mtc;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.CursorLoader;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;

import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Xml;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;


/**
 * A login screen that offers login via email/password.

 */
public class LoginActivity extends Activity{

    /**
     * A dummy authentication store containing known user names and passwords.
     * TODO: remove after connecting to a real authentication system.
     */
    private static final String[] DUMMY_CREDENTIALS = new String[]{
            "foo@example.com:hello", "bar@example.com:world"
    };
    /**
     * Keep track of the login task to ensure we can cancel it if requested.
     */
    private UserLoginTask mAuthTask = null;

    // UI references.
    private TextView mLoginView;
    private EditText mPasswordView;
    private View mProgressView;
    private View mConnectBtn;
    private View mLoginFormView;
    private View mImageLogin;
    private TextView settingLink, refreshLink, changePortLink;
    private CheckBox memoCheck;
    int port = 23;
    String strError, myIpAdress, server, username, password, host;
    TextView errorText, ipText;
    private ArrayList<String> info;
    private Boolean savedSession=false;
    String xmlFilePath = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        // Set up the login form.
        mLoginView = (TextView) findViewById(R.id.login);

        mPasswordView = (EditText) findViewById(R.id.password);
        mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
                if (id == R.id.login || id == EditorInfo.IME_NULL) {
                    attemptLogin();
                    return true;
                }
                return false;
            }
        });

        mLoginFormView = findViewById(R.id.login_form);
        mProgressView = findViewById(R.id.login_progress);

        mConnectBtn = findViewById(R.id.buttonSignIn);
        mConnectBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                animateSimpleButton(view);
                attemptLogin();
            }
        });

        mImageLogin = findViewById(R.id.imageViewLogin);
        mImageLogin.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                animateSimpleButton(view);
            }
        });


        settingLink = (TextView)findViewById(R.id.textViewSetWifi);
        refreshLink = (TextView)findViewById(R.id.textViewRefresh);
        changePortLink = (TextView)findViewById(R.id.textViewChangePort);
        memoCheck = (CheckBox)findViewById(R.id.checkRememberMe);
        errorText = (TextView)findViewById(R.id.textViewError);
        ipText = (TextView)findViewById(R.id.host);
        Button buttonConnect = (Button)findViewById(R.id.buttonSignIn);

        settingLink.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
                refreshLink.setVisibility(View.VISIBLE);
            }});
        changePortLink.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                changePort();
            }});
        refreshLink.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                getWifiInfo();
            }});

        if(getWifiInfo() == 0){
            savedSession = readSavedSession();
            if (savedSession){
                buttonConnect.performClick();
            }
        }

        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    }

    private void animateSimpleButton(View v) {
        v.startAnimation(AnimationUtils.loadAnimation(this, R.anim.fadein));
    }


    /**
     * Attempts to sign in or register the account specified by the login form.
     * If there are form errors (invalid email, missing fields, etc.), the
     * errors are presented and no actual login attempt is made.
     */
    public void attemptLogin() {
        if (mAuthTask != null) {
            return;
        }

        // Reset errors.
        mLoginView.setError(null);
        mPasswordView.setError(null);

        // Store values at the time of the login attempt.
        String email = mLoginView.getText().toString();
        String password = mPasswordView.getText().toString();

        boolean cancel = false;
        View focusView = null;


        // Check for a valid password, if the user entered one.
        if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) {
            mPasswordView.setError(getString(R.string.error_invalid_password));
            focusView = mPasswordView;
            cancel = true;
        }

        // Check for a valid email address.
        if (TextUtils.isEmpty(email)) {
            mLoginView.setError(getString(R.string.error_field_required));
            focusView = mLoginView;
            cancel = true;
        } else if (!isEmailValid(email)) {
            mLoginView.setError(getString(R.string.error_invalid_email));
            focusView = mLoginView;
            cancel = true;
        }

        if (cancel) {
            // There was an error; don't attempt login and focus the first
            // form field with an error.
            focusView.requestFocus();
        } else {
            // Show a progress spinner, and kick off a background task to
            // perform the user login attempt.
            showProgress(true);
            mAuthTask = new UserLoginTask(email, password);
            mAuthTask.execute((Void) null);


        }
    }
    private boolean isEmailValid(String email) {
        //TODO: Replace this with your own logic
        //return email.contains("@");
        return true;
    }

    private boolean isPasswordValid(String password) {
        //TODO: Replace this with your own logic
        //return password.length() > 4;
        return true;
    }

    /**
     * Shows the progress UI and hides the login form.
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
    public void showProgress(final boolean show) {
        // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
        // for very easy animations. If available, use these APIs to fade-in
        // the progress spinner.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
            int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);

            mConnectBtn.setVisibility(show ? View.GONE : View.VISIBLE);
            mConnectBtn.animate().setDuration(shortAnimTime).alpha(
                    show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mConnectBtn.setVisibility(show ? View.GONE : View.VISIBLE);
                }
            });

            mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
            mProgressView.animate().setDuration(shortAnimTime).alpha(
                    show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
                }
            });
        } else {
            // The ViewPropertyAnimator APIs are not available, so simply show
            // and hide the relevant UI components.
            mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
            mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
        }
    }

    /**
     * Represents an asynchronous login/registration task used to authenticate
     * the user.
     */
    public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {

        private final String mEmail;
        private final String mPassword;

        UserLoginTask(String email, String password) {
            mEmail = email;
            mPassword = password;
        }

        @Override
        protected Boolean doInBackground(Void... params) {
            // TODO: attempt authentication against a network service.

            try {
                // Simulate network access.
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                return false;
            }

            for (String credential : DUMMY_CREDENTIALS) {
                String[] pieces = credential.split(":");
                if (pieces[0].equals(mEmail)) {
                    // Account exists, return true if the password matches.
                    return pieces[1].equals(mPassword);
                }
            }

            // TODO: register the new account here.
            return true;
        }

        @Override
        protected void onPostExecute(final Boolean success) {
            mAuthTask = null;
            showProgress(false);

            if (success) {
                finish();
                startActivity(new Intent(LoginActivity.this, MainActivity.class));
            } else {
                mPasswordView.setError(getString(R.string.error_incorrect_password));
                mPasswordView.requestFocus();
            }
        }

        @Override
        protected void onCancelled() {
            mAuthTask = null;
            showProgress(false);
        }
    }

    void changePort() {
        final Dialog dialog = new Dialog(this);
        dialog.setContentView(R.layout.activity_change_port_dialog);
        dialog.setTitle("Port d'accès au routeur");

        // set the custom dialog components - text, image and button
        final TextView text = (TextView) dialog.findViewById(R.id.editPortNumber);
        text.setText(String.valueOf(port));

        Button cancelButton = (Button) dialog.findViewById(R.id.port_change_no);
        cancelButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

        Button okButton = (Button) dialog.findViewById(R.id.port_change_yes);
        okButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!text.getText().toString().equals("")){
                    port = Integer.parseInt(text.getText().toString());
                    strError = "Vous avez choisi comme port : " + port + ", veuillez réessayer la connexion.";
                    updateScreen(strError);
                }
                dialog.dismiss();
            }
        });

        dialog.show();
    }

    void updateScreen(String strError) {
        if(strError.equals("")){
            errorText.setText("");
            errorText.setVisibility(View.INVISIBLE);
        }else{
            errorText.setText(strError);
            errorText.setVisibility(View.VISIBLE);
        }
        settingLink.setVisibility(View.INVISIBLE);
        refreshLink.setVisibility(View.INVISIBLE);
        changePortLink.setVisibility(View.INVISIBLE);
    }

    int getWifiInfo() {
        info = new ArrayList<String>();
        if ( Util.isUsingWiFi(getBaseContext())){
            info = (ArrayList<String>)Util.getWifiInfo(getBaseContext());
            ipText.setText(info.get(0));
            myIpAdress = info.get(1);
            errorText.setText("");
            settingLink.setVisibility(View.INVISIBLE);
            refreshLink.setVisibility(View.INVISIBLE);
            return 0;
        }else{
            errorText.setText("Wifi inactif, veuillez activer votre connexion wifi en cliquant sur le lien suivant");
            settingLink.setVisibility(View.VISIBLE);
            return -1;
        }
    }

    void hideKeyBoard(){
        //for keyboard
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(ipText.getWindowToken(), 0);
    }

    Boolean readSavedSession() {
        ArrayList<String> userData = new ArrayList<String>();
        String data=null;
        xmlFilePath = getFilesDir().getAbsolutePath() + File.separator + "userData";

        try {
            FileInputStream fis = new FileInputStream(xmlFilePath);
            InputStreamReader isr = new InputStreamReader(fis);
            char[] inputBuffer = new char[fis.available()];
            isr.read(inputBuffer);
            data = new String(inputBuffer);
            isr.close();
            fis.close();
        } catch (FileNotFoundException e3) {
            File newXmlFile = new File(xmlFilePath);
            try {
                newXmlFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            e3.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        XmlPullParserFactory factory = null;
        try {
            factory = XmlPullParserFactory.newInstance();
        } catch (XmlPullParserException e2) {
            e2.printStackTrace();
            return false;
        }

        factory.setNamespaceAware(true);
        XmlPullParser xpp = null;
        try {
            xpp = factory.newPullParser();
        } catch (XmlPullParserException e2) {
            e2.printStackTrace();
            return false;
        }

        try{
            xpp.setInput( new StringReader(data) );
        } catch (XmlPullParserException e1) {
            e1.printStackTrace();
            return false;
        }

        int eventType = 0;
        try{
            eventType = xpp.getEventType();
        } catch (XmlPullParserException e1) {
            e1.printStackTrace();
            return false;
        }

        while (eventType != XmlPullParser.END_DOCUMENT){
            if(eventType == XmlPullParser.START_DOCUMENT) {
                System.out.println("Start document");
            }else if(eventType == XmlPullParser.START_TAG) {
                System.out.println("Start tag "+xpp.getName());
            }else if(eventType == XmlPullParser.END_TAG) {
                System.out.println("End tag "+xpp.getName());
            }else if(eventType == XmlPullParser.TEXT) {
                userData.add(xpp.getText());
            }
            try{
                eventType = xpp.next();
            }catch (XmlPullParserException e) {
                e.printStackTrace();
                return false;
            }catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        try {
            username=userData.get(0);
            password=userData.get(1);
            host=userData.get(2);
            port=Integer.parseInt(userData.get(3));
            if(!username.equals("") && !host.equals("") && port > 0){
                System.out.println(username+password+host+port);
                return true;
            }
        } catch (IndexOutOfBoundsException e) {
            return false;
        }
        return false;
    }

    @Override
    public void onBackPressed() {
        new AlertDialog.Builder(this)
                .setMessage("Voulez vous vraiment quitter MTC ?")
                .setCancelable(false)
                .setPositiveButton("Oui", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        finish();
                    }
                })
                .setNegativeButton("Non", null)
                .show();
    }

    void saveSession() {
        try {
            FileOutputStream fileos = new FileOutputStream(xmlFilePath);
            XmlSerializer xmlSerializer = Xml.newSerializer();
            StringWriter writer = new StringWriter();
            xmlSerializer.setOutput(writer);
            xmlSerializer.startDocument("UTF-8", true);
            xmlSerializer.startTag(null, "userdata");

            xmlSerializer.startTag(null, "username");
            xmlSerializer.text(username);
            xmlSerializer.endTag(null, "username");

            xmlSerializer.startTag(null, "password");
            xmlSerializer.text(password);
            xmlSerializer.endTag(null, "password");

            xmlSerializer.startTag(null, "host");
            xmlSerializer.text(host);
            xmlSerializer.endTag(null, "host");

            xmlSerializer.startTag(null, "port");
            xmlSerializer.text(String.valueOf(port));
            xmlSerializer.endTag(null, "port");

            xmlSerializer.endTag(null, "userdata");
            xmlSerializer.endDocument();
            xmlSerializer.flush();
            String dataWrite = writer.toString();
            fileos.write(dataWrite.getBytes());
            fileos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}



